/*
This file is part of Docking@Home.
http://docking.gcl.cis.udel.edu
Copyright (C) 2009 University of Delaware

Docking@Home is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

Docking@Home is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Docking@Home.  If not, see <http://www.gnu.org/licenses/>.
*/
/*
	Filename: TextButton.cpp
	Description: A button in the UI that is represented by text
	Revision History: 
		Created - 01/14/08
	Author: Robert Keller (01/14/08 -> current)
*/

#include "TextButton.h"
#include "Button.h"

// ------------------------------------------------------------
// Constructor / Destructor
// ------------------------------------------------------------

TextButton::TextButton ()
{
	init("", 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.1f);
}// TextButton

TextButton::TextButton(const char n[25])
{
	init(n, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.1f);
}// TextButton

TextButton::TextButton(const char n[25], float xVal, float yVal)
{
	init(n, xVal, yVal, 1.0f, 1.0f, 1.0f, 0.1f);
}// TextButton

TextButton::TextButton(const char n[25], float xVal, float yVal, 
	float xs, float ys, float zs, float a)
{
	init(n, xVal, yVal, xs, ys, zs, a);
}// TextButton

TextButton::~TextButton ()
{
}// ~TextButton

// ------------------------------------------------------------
// Initialization Functions
// ------------------------------------------------------------

void TextButton::init (const char n[TEXTIMAGE_MAX_NAME_LENGTH],
	float xVal, float yVal, float xs, float ys,
	float zs, float a)
{
	setName(n);

	// Set the scales - must make y negative since it has to
	// flip the text to draw right-side up
	textXScale = xs;
	textYScale = -ys;
	textZScale = zs;

	// Set the alpha value
	alpha = a;

	determineWidthHeight();

	// Since text is flipped when drawing, we need to adjust
	// the x and y values so they are the top left of the 
	// text and not the bottom left

	x = xVal;
	y = yVal - height;
}// init

// ------------------------------------------------------------
// Member Modifiers
// ------------------------------------------------------------

void TextButton::setName (const char n[BUTTON_MAX_NAME_LENGTH])
{
	Button::setName(n);

	determineWidthHeight();

}// setName

void TextButton::setTextXScale (float x)
{
	textXScale = x;
}// setTextXScale

void TextButton::setTextYScale (float y)
{
	textYScale = -y;
}// setTextYScale

void TextButton::setTextZScale (float z)
{
	textZScale = z;
}// setTextZScale

void TextButton::determineWidthHeight()
{
	glHelper->getDrawnTextProperties(name, 0, &textWidth, 
		&textMax_ascent, &textMax_descent);

	width = (float)textWidth * textXScale;
	height = (float)(textMax_ascent + textMax_descent) 
		* -textYScale;

}// determineWidthHeight

// ------------------------------------------------------------
// Required Button Functions
// ------------------------------------------------------------

// Name: determineState
// Description: Determines if the button has been either selected,
//	hovered over, or nothing. This does it by checking whether or
//	not the provided coordinates are within the boundaries of the
//	button and whether it has been clicked
// Parameters:
//	mouseX, x coordinates
//	mouseY, y coordinates
//	clicked, whether or not a button was clicked
// Returns: true if the button now is selected, false otherwise

bool TextButton::determineState (int mouseX, int mouseY, int clicked)
{
	glHelper->drawRectWH(currX + currXShift, 
		currY - currYShift, 
		currWidth, currHeight, unselectedColor);

	if (mouseX <= currX + currXShift + currWidth
			&& mouseX >= currX + currXShift
			&& mouseY <= currY - currYShift + currHeight
			&& mouseY >= currY - currYShift)
	{
		// Button was selected
		if (clicked)
		{
			// Check if this action should be maintained after 
			// a single click
			if (bHoldSelection)
				bSelected = true;
			
			state = SELECTED;

			return true;
		}// if
		else
			state = HOVER;
	}// if
	else
	{
		(bSelected == true) ? state = SELECTED : state = UNSELECTED;
	}// else

	return false;

}// determineState

void TextButton::resize (float scaleX, float scaleY)
{
	currWidth = width * scaleX;
	currHeight = height * scaleY;

	currX = x * scaleX;
	currY = y * scaleY;

	currTextXScale = scaleX * textXScale;
	currTextYScale = scaleY * textYScale;

	currXShift = glHelper->AVERAGE_TEXT_SHIFT_RIGHT * scaleX;
	currYShift = glHelper->AVERAGE_TEXT_SHIFT_UP * scaleY;

}// resize

// Maintains the same placement on the bottom of the screen.
//  - The text will be enlarged but the bottom pixels will 
//    be the same distance from the bottom of the screen
void TextButton::resizeSameBottom (float scaleX, float scaleY,
	int standardHeight, int windowHeight)
{
	currWidth = width * scaleX;
	currHeight = height * scaleY;

	currX = x * scaleX;
	currY = windowHeight - (standardHeight - y) 
		- (currHeight - height);

	currTextXScale = scaleX * textXScale;
	currTextYScale = scaleY * textYScale;

	currXShift = glHelper->AVERAGE_TEXT_SHIFT_RIGHT * scaleX;
	currYShift = glHelper->AVERAGE_TEXT_SHIFT_UP * scaleY;

}// resizeSameBottom

// Maintains the same placement on the left of the screen.
//  - The text will be enlarged but the left pixels will 
//    be the same distance from the left side of the screen
void TextButton::resizeSameLeft (float scaleX, float scaleY,
	int standardWidth, int windowWidth)
{
	currWidth = width * scaleX;
	currHeight = height * scaleY;

	currX = x;
	currY = y * scaleY;

	currTextXScale = scaleX * textXScale;
	currTextYScale = scaleY * textYScale;

	currXShift = glHelper->AVERAGE_TEXT_SHIFT_RIGHT * scaleX;
	currYShift = glHelper->AVERAGE_TEXT_SHIFT_UP * scaleY;

}// resizeSameLeft

void TextButton::draw ()
{
	switch (state)
	{
	case UNSELECTED:
		drawUnselected();
		break;
	case SELECTED:
		drawSelected();
		break;
	case HOVER:
		drawHovered();
		break;
	}// switch
}// draw

void TextButton::drawSelected ()
{
	glHelper->drawText(alpha, currX, currY + currHeight, 0, 
		currTextXScale, currTextYScale, 
		textZScale, selectedColor, 0, name);
}// draw

void TextButton::drawUnselected ()
{
	glHelper->drawText(alpha, currX, currY + currHeight, 0, 
		currTextXScale, currTextYScale, 
		textZScale, unselectedColor, 0, name);
}// draw

void TextButton::drawHovered ()
{
	glHelper->drawText(alpha, currX, currY + currHeight, 0,
		currTextXScale, currTextYScale,  
		textZScale, hoverColor, 0, name);
}// draw
